class Txt2tagsLexer extends Lexer ;

options 
{
	k = 5 ;
	filter = true ;
	caseSensitive = false ;
}

BOLDSYMBOL :
	"**" ;
		
ITALICSYMBOL :
	"//" ;
	
UNDERLINESYMBOL :
	"__" ;
	
STRIKESYMBOL :
	"--" ;

MONOSPACESYDMBOL :
	"``" ;	

TITLESYMBOL :
	('=')+ ;

ORDEREDTITLESYMBOL :
	('+')+ ;
	
LIST_OR_COMMENT_OR_NEWLINE :
	NEWLINE
	( 
		((SPACE)*
			"+"
			{ 
				$setType(ORDEREDLIST) ; 
			}
			| "-"
			{
				$setType(UNORDEREDLIST) ;
			} 
			| ":"
			{
				$setType(DEFINITIONLIST) ;
			}
		)
		| '%'
		{
			$setType(COMMENT) ;
		}
		| ()
		{
			$setType(NEWLINE) ; 
		}
	);	
			
NUMBER :
	(DIGIT)+ ;
	
WORD :
	(LETTER | DIGIT)+ ;

PUNCTUATIONMARK :
	']' | '\\' | '[' |'$' | '_' | '%' | '(' | ')' | ',' | '?' | ';' | '!' | '"' | '-' | '/' | ':' | '='  | '.' | '#' | '<' | '@' | '\'' | '*' | '{' ;

NEWLINE :
	( "\r\n" {newline(); }
	| "\n" { newline(); }
	) ; 

protected LETTER :
	'a'..'z' ;
	
protected DIGIT :
	'0'..'9' ;
		
WHITESPACE :
    SPACE
    | '\t'
    | '\f' ; 

protected SPACE :
	' ' ;

class Txt2tagsParser extends Parser;

options 
{
  buildAST=true;
}

txt2tagsFile! :
	node1:txt2tagsMarkupSection node2:txt2tagsFile
		{
			#txt2tagsFile = new DataModel((IComponent)#node1, (IComponent)#node2) ;
		}
	| node3:textBlock node4:txt2tagsFile 
		{ 
			#txt2tagsFile = new DataModel(new Text(#node3.getText(), null), (IComponent)#node4) ; 
		}
	| n:newLine node5:txt2tagsFile
		{ 
			#txt2tagsFile = new DataModel((IComponent)#n, (IComponent)#node5) ; 
		}
	| ()
		{ #txt2tagsFile = null ; }
		;
		
txt2tagsMarkupSection :
	(comment | list | title | orderedTitle | boldText | underlineText | italicText | deletedText | monospacedText) ;

list :
	orderedList | unorderedList | definitionList;
	
orderedList! :
	l:ORDEREDLIST
	{
		#orderedList = new OrderedList("") ;
		int level = #l.getText().length() / 2 ;
		((AbstractWikiList)#orderedList).setLevel(level) ;
	} ;

unorderedList! :
	l:UNORDEREDLIST
	{
		#unorderedList = new UnorderedList("") ;
		int level = #l.getText().length() / 2 ;
		((AbstractWikiList)#unorderedList).setLevel(level) ;
	} ;

definitionList! :
	l:DEFINITIONLIST
	{
		
	} ;

boldText! :
	BOLDSYMBOL node:text BOLDSYMBOL 
		{ #boldText = new Text(#node.getText(), TextFormatting.BOLD) ; };

italicText! :
	ITALICSYMBOL node:text ITALICSYMBOL 
		{ #italicText = new Text(#node.getText(), TextFormatting.ITALIC) ; };

underlineText! :
	UNDERLINESYMBOL node:text UNDERLINESYMBOL
		{ #underlineText = new Text(#node.getText(), TextFormatting.UNDERLINE) ; };

deletedText! :
	STRIKESYMBOL node:text STRIKESYMBOL
	{
		#deletedText = new Text(#node.getText(), TextFormatting.DELETED) ;	
	};
	
monospacedText! :
	MONOSPACESYDMBOL node:text MONOSPACESYDMBOL
	{
		#monospacedText = new Text(#node.getText(), TextFormatting.MONOSPACED)  ;
	};
	
comment! :
	COMMENT t:textLine 
	{ 
		#comment = new Text(#t.getText(), TextFormatting.COMMENT) ;
	} ;
	
newLine! :
	NEWLINE 
	{
		#newLine = new Text("\n", null) ;	
	} ;

text! :
	t1:textBlock t2:text 
		{ 
			String t2Text = "" ;
			if(#t2 != null)
				t2Text = #t2.getText() ;
			#text = new Text(#t1.getText() + t2Text, null) ;
		}  
	| n:newLine t:text
		{
			String tText = "" ;
			if(#t != null)
				tText = #t.getText() ;
		 	#text = new Text(#n.getText() + tText, null) ;
		}  
	| ()
		{
			 #text = null ; 
		} ;

title! :
	t:TITLESYMBOL node:text TITLESYMBOL 
	{
		#title = new Headline(#node.getText(), #t.getText().length()) ; 
	};

orderedTitle! :
	ORDEREDTITLESYMBOL node:text t:ORDEREDTITLESYMBOL 
	{
		#orderedTitle = new Headline(#node.getText(), #t.getText().length()) ; 
		((Headline)#orderedTitle).setOrdered() ;
	};
	
textBlock :
	(WHITESPACE | WORD | NUMBER  | PUNCTUATIONMARK); 

textLine! : 
	(t1:textBlock t2:textLine)
	{
		String t2Text = "" ;
		if(#t2 != null)
			t2Text = #t2.getText() ;
		#textLine = new Text(#t1.getText() + t2Text, null) ;
	}
	| n:newLine
	{
		#textLine = null ;
	} ;